package com.zxw.user.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.zxw.common.core.base.constant.SysConstants;
import com.zxw.common.web.annotation.InitInsertInfo;
import com.zxw.common.web.util.JwtUtils;
import com.zxw.user.domain.dto.LoginRouteDTO;
import com.zxw.user.domain.dto.RoleMenuDTO;
import com.zxw.user.domain.entity.RoleMenu;
import com.zxw.user.domain.vo.RoleButtonUpdateVO;
import com.zxw.user.domain.vo.RoleMenuUpadteVO;
import com.zxw.user.mapper.RoleMenuMapper;
import com.zxw.user.service.RoleMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Xuewei.Zhang
 * @since 2022-02-28
 */
@Service
@RequiredArgsConstructor
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuService {

    private final RoleMenuMapper roleMenuMapper;

    /**
     * 获取登陆路由菜单
     *
     * @return
     */
    @Override
    public List<LoginRouteDTO> getLoginRouteMenu() {
        Long companyId = JwtUtils.getCompanyId();
        List<RoleMenuDTO> roleMenuDTOList = roleMenuMapper.getAllMenuByCompanyId(companyId);
        List<LoginRouteDTO> loginRouteDTOList = recursiveGenerateRouteMenu(SysConstants.ROOT_MENU_ID, roleMenuDTOList);
        return loginRouteDTOList;
    }

    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        Long companyId = JwtUtils.getCompanyId();
        return roleMenuMapper.selectMenuIdByRoleIdAndCompanyId(roleId, companyId);
    }

    @Override
    @InitInsertInfo
    public void update(RoleMenuUpadteVO roleMenuUpadteVO) {
        Long roleId = roleMenuUpadteVO.getRoleId();
        Long companyId = roleMenuUpadteVO.getCompanyId();
        List<Long> menuIds = roleMenuUpadteVO.getMenuIds();
        List<Long> oldMenuIds = this.getMenuIdsByRoleId(roleId);
        List<Long> sortedOldMenuIds = oldMenuIds.stream().sorted().collect(Collectors.toList());
        List<Long> sortedMenuIds = menuIds.stream().sorted().collect(Collectors.toList());
        if (CollectionUtil.isEqualList(sortedMenuIds, sortedOldMenuIds)) {
            return;
        }
        // 删除此次移除的菜单数据
        if (CollectionUtil.isNotEmpty(sortedOldMenuIds)) {
            List<Long> deleteMenuIds = sortedOldMenuIds.stream().filter(item -> !sortedMenuIds.contains(item)).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(deleteMenuIds)) {
                this.remove(new LambdaQueryWrapper<RoleMenu>()
                        .eq(RoleMenu::getCompanyId, companyId)
                        .eq(RoleMenu::getRoleId, roleId)
                        .in(RoleMenu::getMenuId, deleteMenuIds)
                );
            }
        }
        // 新增此次保存 不存在的菜单数据
        if (CollectionUtil.isNotEmpty(sortedMenuIds)) {
            List<Long> addMenuIds = sortedMenuIds.stream().filter(item -> !sortedOldMenuIds.contains(item)).collect(Collectors.toList());
            List<RoleMenu> roleMenuList = new ArrayList<>();
            for (int i = 0; i < addMenuIds.size(); i++) {
                RoleMenu roleMenu = new RoleMenu();
                BeanUtils.copyProperties(roleMenuUpadteVO, roleMenu);
                roleMenu.setMenuId(addMenuIds.get(i));
                roleMenuList.add(roleMenu);
            }
            if (roleMenuList.size() > 0)
                this.saveBatch(roleMenuList);
        }
    }

    /**
     * 递归组装菜单
     *
     * @param parentId
     * @param roleMenuDTOList
     * @return
     */
    private List<LoginRouteDTO> recursiveGenerateRouteMenu(Long parentId, List<RoleMenuDTO> roleMenuDTOList) {
        List<LoginRouteDTO> endList = new ArrayList<>();
        Optional.ofNullable(roleMenuDTOList).ifPresent(menus -> menus.stream().filter(menu -> menu.getParentId().equals(parentId))
                .forEach(menu -> {
                    LoginRouteDTO loginRouteDTO = new LoginRouteDTO();
                    loginRouteDTO.setComponent(menu.getComponent());
                    loginRouteDTO.setName(menu.getName());
                    loginRouteDTO.setPath(menu.getPath());

                    LoginRouteDTO.Meta meta = new LoginRouteDTO.Meta();
                    meta.setIcon(menu.getIcon());
                    meta.setRoles(menu.getRoles());
                    meta.setTitle(menu.getName());
                    loginRouteDTO.setMeta(meta);
                    List<LoginRouteDTO> children = recursiveGenerateRouteMenu(menu.getId(), roleMenuDTOList);
                    if (CollectionUtil.isNotEmpty(children)) {
                        meta.setAlwaysShow(Boolean.TRUE);
                    }
                    loginRouteDTO.setChildren(children);
                    endList.add(loginRouteDTO);
                }));
        return endList;
    }


}
